package com.zmc.admin.application.impl;

import com.zmc.admin.application.UserApplicationService;
import com.zmc.admin.infrastructure.constant.ErrorCodeConstants;
import com.zmc.admin.infrastructure.entity.SysUserEntity;
import com.zmc.admin.infrastructure.entity.SysUserPostEntity;
import com.zmc.admin.infrastructure.entity.SysUserRoleEntity;
import com.zmc.admin.infrastructure.service.SysUserPostService;
import com.zmc.admin.infrastructure.service.SysUserRoleService;
import com.zmc.admin.infrastructure.service.SysUserService;
import com.zmc.common.annotation.PreventRepeatSubmit;
import com.zmc.common.enums.RequestSourceEnum;
import com.zmc.common.exception.base.WebDisplayException;
import com.zmc.common.utils.MD5Utils;
import com.zmc.common.utils.StringUtils;
import com.zmc.common.utils.token.AuthTokenService;
import com.zmc.common.utils.uuid.IdUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @Author：zmc
 * @Date：2025/1/17 12:28
 */
@Service
public class UserApplicationServiceImpl implements UserApplicationService {

    @Autowired
    private SysUserService userService;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private SysUserPostService sysUserPostService;

    @Autowired
    private AuthTokenService authTokenService;


    @Override
    @Transactional
    @PreventRepeatSubmit(lockByPerson = true, source = RequestSourceEnum.MANAGE)
    public void updateUser(SysUserEntity user) {
        //前置检查
        userFrontCheck(user);
        //更新角色
        sysUserRoleService.deleteUserRoleByUserId(user.getUserId());
        updateUserRole(user);
        //更新岗位
        sysUserPostService.deleteUserPostByUserId(user.getUserId());
        updateUserPost(user);
        //更新用户
        user.setUpdateBy(authTokenService.getUserInfo().getUsername());
        userService.updateById(user);
    }

    @Override
    @Transactional
    @PreventRepeatSubmit(lockByPerson = true, source = RequestSourceEnum.MANAGE)
    public void saveUser(SysUserEntity user) {
        //前置检查
        userFrontCheck(user);
        //保存用户
        String salt = IdUtils.fastUUID().substring(0, 16);
        user.setPassword(MD5Utils.encrypt(user.getPassword(), salt));
        user.setSalt(salt);
        user.setCreateBy(authTokenService.getUserInfo().getUsername());
        userService.save(user);
        //保存角色信息
        updateUserRole(user);
        //保存岗位信息
        updateUserPost(user);
    }

    @Override
    @Transactional
    @PreventRepeatSubmit(lockByPerson = true, source = RequestSourceEnum.MANAGE)
    public void removeUser(Long userId) {
        if (Objects.equals(authTokenService.getUserInfo().getUserId(), userId)) {
            throw new WebDisplayException(ErrorCodeConstants.USER_DELETE_EXCEPTION);
        }
        //删除用户关联角色
        sysUserRoleService.deleteUserRoleByUserId(userId);
        //删除用户关联岗位
        sysUserPostService.deleteUserPostByUserId(userId);
        //删除用户
        userService.removeById(userId);
    }

    /**
     * 用户前置检查
     * */
    public void userFrontCheck(SysUserEntity user){
        if (!userService.checkUserNameUnique(user)) {
            throw new WebDisplayException(ErrorCodeConstants.USERNAME_USED_EXCEPTION);
        } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
            throw new WebDisplayException(ErrorCodeConstants.PHONE_USED_EXCEPTION);
        } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
            throw new WebDisplayException(ErrorCodeConstants.EMAIL_USED_EXCEPTION);
        }else if (CollectionUtils.isEmpty(user.getRoleIds())){
            throw new WebDisplayException(ErrorCodeConstants.ROLE_PERMISSION_EXCEPTION);
        }
    }

    /**
     * 更新用户角色信息
     * */
    @Transactional
    public void updateUserRole(SysUserEntity user) {
        List<SysUserRoleEntity> userRoleList = new ArrayList<>();
        user.getRoleIds().forEach(roleId -> {
            SysUserRoleEntity entity = new SysUserRoleEntity();
            entity.setUserId(user.getUserId());
            entity.setRoleId(roleId);
            userRoleList.add(entity);
        });
        sysUserRoleService.insertBatch(userRoleList);
    }

    @Transactional
    public void updateUserPost(SysUserEntity user) {
        List<SysUserPostEntity> userPostList = new ArrayList<>();
        user.getPostIds().forEach(postId -> {
            SysUserPostEntity entity = new SysUserPostEntity();
            entity.setUserId(user.getUserId());
            entity.setPostId(postId);
            userPostList.add(entity);
        });
        sysUserPostService.insertBatch(userPostList);
    }

}
